#pragma once
#include <iostream>
#include <functional>
#include "Log.hpp"
#include "Socket.hpp"
#include "Protocol.hpp"

using process_t = std::function<std::shared_ptr<Response>(std::shared_ptr<Request>)>;

class IOService
{
public:
    IOService(process_t process) : _process(process) {}

    void IOExcute(SockPtr sock, InetAddr &addr)
    {
        std::string packagestreamqueue;
        while (true)
        {
            ssize_t n = sock->Recv(&packagestreamqueue);
            if (n <= 0)
            {
                LOG(FATAL, "client quit or recv error\n");
                break;
            }
            std::cout << "----------------------------------------" << std::endl;
            std::cout << "packagestreamqueue:\n"
                      << packagestreamqueue << std::endl;
            std::string package = Decode(packagestreamqueue); // 取出有效载荷
            if (package.empty())
                continue;
            auto req = Factory::BuildRequestDefault();
            std::cout << "package:\n"
                      << package << std::endl;
            req->Deserialize(package); // 反序列化
            auto resp = _process(req); // 业务处理

            std::string respjson;
            resp->Serialize(&respjson);
            std::cout << "respjson:\n"
                      << respjson << std::endl;
            respjson = Encode(respjson);
            std::cout << "respjosn add header done:\n"
                      << respjson << std::endl;
            sock->Send(respjson);
        }
    }

private:
    process_t _process;
};